/**
 *  Copyright (C) 2013  Piotr Szczepa�ski
 *
 *   This program is free software: you can redistribute it and/or modify
 *   it under the terms of the GNU General Public License as published by
 *   the Free Software Foundation, either version 3 of the License, or
 *   (at your option) any later version.
 *
 *   This program is distributed in the hope that it will be useful,
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *   GNU General Public License for more details.
 *
 *   You should have received a copy of the GNU General Public License
 *   along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/
package edu.pw.elka.gtsna.coalitionalgames;

import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

/**
 * @author Piotr Lech Szczepa�ski
 * @author P.Szczepanski@ii.pw.edu.pl 
 *
 */
public class CoalitionalStructure {
	
	// the coalitional structure is the list of sets of integers, each set in numerated
	protected List<Set<Integer>> coalitions = new ArrayList<Set<Integer>>();
	// the number of all sets inside coalition structure
	protected Set<Integer> coalitionNumbers = new LinkedHashSet<Integer>();
	
	protected Map<Integer,Integer> agentsCoalitionNumber = new HashMap<Integer,Integer>();
	

	public List<Set<Integer>> getCoalitions(){
		return coalitions;
	}
	
	
	public void addCoalition(Set<Integer> coalition){
		coalitions.add(coalition);
		coalitionNumbers.add(coalitions.size()-1);
		
		for (int a: coalition){
			agentsCoalitionNumber.put(a, coalitions.size()-1);
		}
	}
	
	public void addAgent(int agent, int coalitionNumber){
		if (coalitions.size() <= coalitionNumber){
			for (int i=coalitions.size(); i<= coalitionNumber; i++){
				coalitions.add(new LinkedHashSet<Integer>());
			}			
		}
		if (coalitions.get(coalitionNumber).isEmpty()) {
			coalitionNumbers.add(coalitionNumber);
		}
		coalitions.get(coalitionNumber).add(agent);
		agentsCoalitionNumber.put(agent, coalitionNumber);
	}
	
	public Collection<Integer> getStructersNumbers() {
		return coalitionNumbers;
	}
	
	public Set<Integer> getAgentsFromCoalitions(Set<Integer> M){
		Set<Integer> Q = new LinkedHashSet<Integer>();
		for(int m: M){
			Q.addAll(coalitions.get(m));
		}
		return Q;
	}
	
	public Set<Integer> getAgentCoalition(int a){
		return coalitions.get(agentsCoalitionNumber.get(a));
	}
	
	public Set<Integer> getCoalition(int number){
		return coalitions.get(number);
	}
	
	public int getAgentCoalitionNumber(int a){
		return agentsCoalitionNumber.get(a);
	}
	
	public int size(){
		return coalitionNumbers.size();
	}
	
	public int size(int a){
		return getAgentCoalition(a).size();
	}
	
	public String toString(){
		StringBuilder sb = new  StringBuilder();
		for (Set<Integer> coalition: coalitions){
			sb.append(coalition.toString()+"\n");	
		}
		return sb.toString();
	}
	
	public void print(){
		for (Set<Integer> coalition: coalitions){
			System.out.println(coalition);	
		}
	}
	
	
}
